package com.xiaoq.order.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaoq.apis.interpreter.IInterpreterApi;
import com.xiaoq.apis.interpreter.InterCalendar4OrderVo;
import com.xiaoq.apis.interpreter.Interpreter4OrderVo;
import com.xiaoq.apis.order.InterOrder4InterCalendarVo;
import com.xiaoq.apis.sites.ISitesApi;
import com.xiaoq.apis.sites.SitesInfo4SocialVo;
import com.xiaoq.apis.user.IUserApi;
import com.xiaoq.apis.user.UserInfo4UserCouponVo;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.order.entity.OrderState;
import com.xiaoq.order.entity.PayState;
import com.xiaoq.order.entity.ShopOrderEntity;
import com.xiaoq.order.entity.ShoppingItem;
import com.xiaoq.order.service.IShopOrderCardService;
import com.xiaoq.order.service.IShopOrderService;
import com.xiaoq.order.vo.*;
import com.xiaoq.shop.entity.SKUEntity;
import com.xiaoq.shop.entity.SPUEntity;
import com.xiaoq.shop.entity.UserCouponEntity;
import com.xiaoq.shop.service.ISKUService;
import com.xiaoq.shop.service.ISPUService;
import com.xiaoq.shop.service.IUserCouponService;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/api/v1/inter_orders")
@Api(tags = "C端讲解员订单相关")
class InterpreterOrderEndpoint2C {

    private static final Logger LOGGER = LoggerFactory.getLogger(InterpreterOrderEndpoint2C.class);
    private static final class ConfirmPayResponse extends GenericDataResponse<ConfirmPayVo> {}
    private static final class GoPayResponse extends GenericDataResponse<GoPayVo> {}
    private static final class InterOrderResponse extends GenericListResponse<ShopOrderVo> {}
    private static final class PrePayOrderDataResponse extends GenericDataResponse<PrePayOrder> {}

    @Autowired
    private IUserCouponService userCouponService;

    @Autowired
    private IShopOrderService shopOrderService;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private ISKUService skuService;

    @Autowired
    private ISPUService spuService;

    @Autowired
    private IShopOrderCardService shopOrderCardService;

    @Reference(interfaceClass=IUserApi.class, check=false, version="1.0.0")
    private IUserApi userDubboApi;

    @Reference(interfaceClass=ISitesApi.class, check=false, version="1.0.0")
    private ISitesApi sitesApi;

    @Reference(interfaceClass=IInterpreterApi.class, check=false, version="1.0.0")
    private IInterpreterApi interpreterApi;


    /**
     *  用户提交订单，即改讲解员为服务中的状态， 其他用户不能预约
     * @param request
     * @param interpreterOrderAddition
     * @return
     */
    @ApiOperation(value="提交订单", notes="提交订单")
    @ApiResponses({
            @ApiResponse(code = 200, response = GoPayResponse.class, message = "提交订单")
    })
    @PostMapping(value = "", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?>  commitOrder(
            HttpServletRequest request,
            @RequestBody InterpreterOrderAddition interpreterOrderAddition) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("用户未登录或不存在");
        }

        if(userInfo4UserCouponVo.isAnonymous()){
            return GenericResponse.ng("此账户为匿名登录,暂不能购票,请注册后预约讲解员");
        }

        if(interpreterOrderAddition == null){
            return GenericResponse.ng("RequestBody 不能为空");
        }
        String interpreterId = interpreterOrderAddition.getInterpreterId();
        String sitesId = interpreterOrderAddition.getShopId();
        SKUEntity skuEntity = skuService.getInterpreterSkuById(sitesId, interpreterId);
        if(skuEntity==null || StringUtils.isBlank(skuEntity.getId())){
            return GenericResponse.ng("此讲解员不存在");
        }
        SPUEntity spuEntity = spuService.getByShopIdAndSpuCode(sitesId, skuEntity.getSpuCode());
        if(spuEntity == null){
            return GenericResponse.ng("此讲解员不存在!");
        }
        SitesInfo4SocialVo siteInfo4Social = sitesApi.getSiteInfo4Social(sitesId);
        if(siteInfo4Social==null || StringUtils.isBlank(siteInfo4Social.getName())){
            return GenericResponse.ng("此景区不存在");
        }
        ShopOrderEntity shopOrderEntity = new ShopOrderEntity();
        ShoppingItem newShoppingItem = new ShoppingItem();

        String shopOrderId = idGenerator.nextId();
        shopOrderEntity.setShopOrderId(shopOrderId);
        shopOrderEntity.setId(idGenerator.nextId());
        shopOrderEntity.setUserRealName(interpreterOrderAddition.getUserRealName());
        shopOrderEntity.setCellphoneNumber(interpreterOrderAddition.getCellphoneNumber());
        shopOrderEntity.setShopId(sitesId);
        shopOrderEntity.setUserId(userId);
        shopOrderEntity.setShopName(siteInfo4Social.getName());
        shopOrderEntity.setOrderState(OrderState.WAITPAY.value()); //设置为下单状态
        shopOrderEntity.setPayState(PayState.NOPAYMENT.value()); //设置为待付款
        shopOrderEntity.setTotalAmount((int)(skuEntity.getDiscountPrice()/100.0));
        shopOrderEntity.setInterpreterId(interpreterId);
        shopOrderEntity.setUserCounponId(interpreterOrderAddition.getUserCouponId());
        shopOrderEntity.setCreateTime(System.currentTimeMillis());
        shopOrderEntity.setPayEndTime(new DateTime().plusMinutes(5).getMillis()); //倒计时5分钟
        shopOrderEntity.setUserDeleteFlag(ConstantUtil.NOT_DELETE_STATUS); //设置为未删除
        shopOrderEntity.setInterDeleteFlag(ConstantUtil.NOT_DELETE_STATUS); //设置为未删除
        shopOrderEntity.setOrderType(ConstantUtil.ORDER_TYPE_INTERPRETER);

        newShoppingItem.setDiscountPrice(skuEntity.getDiscountPrice());
        newShoppingItem.setSpecifications(skuEntity.getSpuName());
        newShoppingItem.setSkuCode(skuEntity.getSkuCode());
        newShoppingItem.setNumber(1);
        newShoppingItem.setSpuName(skuEntity.getSpuName());
        newShoppingItem.setPrice(skuEntity.getPrice());
        newShoppingItem.setSpuCode(skuEntity.getSpuCode());
        //设置预约时间， 订单列表排序用
        newShoppingItem.setTravelDate(System.currentTimeMillis());

        //TODO 暂时未添加身份证信息
        /*String idCard = interpreterOrderAddition.getIdCard(); //需替换
        IdcardInfoExtractor idcardInfoExtractor = IdcardValidator.getIdcardInfo(idCard);
        if(idcardInfoExtractor == null){
            return GenericResponse.ng("身份证信息不合法");
        }else {
            ShopOrderCardEntity shopOrderCardEntity = new ShopOrderCardEntity();
            shopOrderCardEntity.setIdCard(idCard);
            shopOrderCardEntity.setId(idGenerator.nextId());
            shopOrderCardEntity.setBirthday(idcardInfoExtractor.getBirthday());
            shopOrderCardEntity.setComeFrom(idcardInfoExtractor.getProvince());
            shopOrderCardEntity.setGender(idcardInfoExtractor.getGenderInt());
            shopOrderCardEntity.setShopId(shopId);
            shopOrderCardEntity.setShopOrderId(orderNo);
            shopOrderCardEntity.setUserId(userId);
            shopOrderCardService.save(shopOrderCardEntity);
        }*/

        //优惠券相关
        long currentMillis = System.currentTimeMillis();
        String userCouponId = interpreterOrderAddition.getUserCouponId();//用户优惠券ID
        boolean useCoupon = false;
        if(StringUtils.isNotBlank(userCouponId)){
            UserCouponEntity userCouponEntity = userCouponService.getUserCouponById(userCouponId);
            if(userCouponEntity != null){
                shopOrderEntity.setShopName(userCouponEntity.getShopName());
            }
            if(userCouponEntity!=null && StringUtils.equals(userId, userCouponEntity.getUserId())
                    && UserCouponEntity.StateEnum.NOUSE.value()==userCouponEntity.getState()
                    && currentMillis<userCouponEntity.getExpirationDate()
                    && userCouponEntity.getEffectiveDate() < currentMillis){

                shopOrderEntity.setUserCounponId(userCouponId);
                shopOrderEntity.setCouponCode(userCouponEntity.getCouponInstanceCode());
                //判断优惠券类型。是否满减或者直接减金额
                if(shopOrderEntity.getTotalAmount() >= userCouponEntity.getMinSpendingAmountForUse()){
                    useCoupon = true;
                    //设置总金额
                    shopOrderEntity.setTotalAmount(shopOrderEntity.getTotalAmount() - userCouponEntity.getDenomination());
                    shopOrderEntity.setTotalMoneyOfUsedCoupons(userCouponEntity.getDenomination());
                }
            }
        }

        InterOrder4InterCalendarVo interOrder4InterCalendarVo = new InterOrder4InterCalendarVo();
        interOrder4InterCalendarVo.setId(idGenerator.nextId());
        interOrder4InterCalendarVo.setContact(interpreterOrderAddition.getUserRealName());
        interOrder4InterCalendarVo.setSitesId(interpreterOrderAddition.getShopId());
        interOrder4InterCalendarVo.setUserId(userId);
        interOrder4InterCalendarVo.setType(10); //预约
        interOrder4InterCalendarVo.setOrderId(shopOrderId);
        interOrder4InterCalendarVo.setMemberCount(interpreterOrderAddition.getMemberCount());
        interOrder4InterCalendarVo.setMemo(interpreterOrderAddition.getMemo());
        interOrder4InterCalendarVo.setStatus(ConstantUtil.INTERPRETER_STATUS_NOT_PAY_WAIT_SERVICE_NOT_APPOINT);
        interOrder4InterCalendarVo.setMobile(interpreterOrderAddition.getCellphoneNumber());
        interOrder4InterCalendarVo.setStartTime(interpreterOrderAddition.getStartTime());
        interOrder4InterCalendarVo.setEndTime(interpreterOrderAddition.getEndTime());
        interOrder4InterCalendarVo.setInterpreterId(interpreterOrderAddition.getInterpreterId());
        interOrder4InterCalendarVo.setMeetPlace(interpreterOrderAddition.getMeetPlace());

        try {
            //锁定讲解员
            boolean lockInterFlag = interpreterApi.updateInter2WaitService(interpreterId, sitesId);
            if(!lockInterFlag){
                return GenericResponse.ng("此讲解员可能已被预约，请选择其他讲解员");
            }
        }catch (Exception e){
            LOGGER.error(e.getMessage(), e);
            LOGGER.info("userId: " + userId + "预约讲解员[" + skuEntity.getSpuName() +"]失败，");
            return GenericResponse.ng("dubbo 远程调用出错");
        }

        try {
            shopOrderEntity.setShoppingItems(Arrays.asList(newShoppingItem));
            shopOrderService.saveShopOrder(shopOrderEntity);
            sitesApi.save(interOrder4InterCalendarVo);
            //锁定优惠券
            if(useCoupon) {
                userCouponService.lockUserCoupon(userCouponId, userId);
            }
            GoPayVo goPayVo = new GoPayVo();
            goPayVo.setOrderNo(shopOrderId);
            return InterpreterOrderEndpoint2C.GoPayResponse.okWithData(goPayVo);
        }catch (Exception e){
            //TODO 如果订单存在，删除订单
            shopOrderService.deleteInterOrderByInterIdAndOrderId(interpreterId, shopOrderId);
            shopOrderService.deleteUserOrderByUserIdAndOrderId(userId, shopOrderId);
            interpreterApi.updateInter2WaitService(interpreterId, sitesId);
            //释放优惠券
            if(useCoupon) {
                userCouponService.releaseUserCoupon(userCouponId, userId);
            }
            LOGGER.error(e.getMessage());
        }

        LOGGER.error("订单提交失败");
        return GenericResponse.ng("订单提交失败");
    }

    @ApiOperation(value="讲解员结束服务", notes="讲解员结束服务")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "讲解员结束服务")
    })
    @PutMapping(value = "/{shopOrderId}/orderstate/endservice", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> endService(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }
        Interpreter4OrderVo interpreter4OrderVo = interpreterApi.getInterByUserId(userId);
        ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderByOrderId(shopOrderId);
        if(shopOrderEntity == null || interpreter4OrderVo==null
                || !StringUtils.equals(shopOrderEntity.getInterpreterId(), interpreter4OrderVo.getId())){
            return GenericResponse.ng("此订单不存在或是别人的订单");
        }
        String interId = shopOrderEntity.getInterpreterId();

        //TODO 修改订单状态
        ShopOrderEntity newShopOrderEntity = new ShopOrderEntity();
        newShopOrderEntity.setShopOrderId(shopOrderId);
        newShopOrderEntity.setOrderState(ConstantUtil.INTERPRETER_CALENDAR_STATUS_COMPLETE);
        boolean updateOrderFlag = shopOrderService.updateShopOrderByOrderId(newShopOrderEntity);

        try {
            boolean successFlag = interpreterApi.updateInter2CanAppoint(interId, shopOrderEntity.getShopId());
            if(!successFlag){
                LOGGER.error("解锁讲解员至可预约状态失败。interId: " + interId + ",orderId: " + shopOrderId);
            }
        }catch (Exception e){
            LOGGER.error("解锁讲解员至可预约状态失败。interId: " + interId + ",orderId: " + shopOrderId + "," + e.getMessage(), e);
        }

        try {
            boolean successFlag = interpreterApi.updateInterCalendarStatus(shopOrderId, ConstantUtil.INTERPRETER_CALENDAR_STATUS_COMPLETE);
            if(!successFlag){
                LOGGER.error("解锁讲解员日历至完成状态失败。interId: " + interId + ",orderId: " + shopOrderId);
            }
        }catch (Exception e){
            LOGGER.error("解锁讲解员日历至完成状态失败。interId: " + interId + ",orderId: " + shopOrderId + "," + e.getMessage(), e);
        }

        if(updateOrderFlag){
            return GenericResponse.ok();
        }
        LOGGER.error("结束服务订单失败,订单ID: " + shopOrderId + ", interId: " + userId);
        return GenericResponse.ng("结束服务订单失败");
    }

    //删除订单
    @ApiOperation(value="删除讲解员订单", notes="删除讲解员订单")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "删除讲解员订单")
    })
    @DeleteMapping(value = "/{shopOrderId}/orderstate/delete", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> deleteOrder(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo == null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }
        Interpreter4OrderVo interpreter4OrderVo = interpreterApi.getInterByUserId(userId);
        if(interpreter4OrderVo == null){
            return GenericResponse.ng("此讲解员不存在");
        }
        boolean delFlag = shopOrderService.deleteInterOrderByInterIdAndOrderId(interpreter4OrderVo.getId(),
                shopOrderId);
        if(delFlag){
            return GenericResponse.ok();
        }
        LOGGER.error("讲解员删除订单失败,订单ID: " + shopOrderId + ", interId: " + userId);
        return GenericResponse.ng("删除订单失败");
    }

    //获取讲解员的订单列表
    @ApiOperation(value="查询讲解员的订单列表", notes="查询讲解员的订单列表")
    @ApiResponses({
            @ApiResponse(code = 200, response = InterOrderResponse.class, message = "查询讲解员的订单列表")
    })
    @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> findInterOrders(
            HttpServletRequest request,
            @ApiParam(required = true, name = "orderState", value = "订单状态:99,所有")
            @RequestParam int orderState) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo = userDubboApi.getUserInfoById(userId);
        if(userInfo==null || StringUtils.isBlank(userInfo.getId())){
            return GenericResponse.ng("此用户不存在或未登录");
        }

        Interpreter4OrderVo interpreter4OrderVo = interpreterApi.getInterByUserId(userId);
        if(interpreter4OrderVo==null || StringUtils.isBlank(interpreter4OrderVo.getId())){
            return GenericResponse.ng("此讲解员不存在");
        }

        List<ShopOrderVo> shopOrderVoList = new ArrayList<>();

        if (orderState == OrderState.ALL.value()) {
            List<ShopOrderEntity> orderEntityList = shopOrderService.getInterpreterOrderList(interpreter4OrderVo.getId(),
                    null,PayState.PAID.value());
            Map<String, ShopOrderEntity> orderId2Order = new LinkedHashMap<>();
            if(CollectionUtils.isEmpty(orderEntityList)){
                return InterOrderResponse.listAndCount(shopOrderVoList, shopOrderVoList.size());
            }
            List<String> orderIdList = new ArrayList<>();
            for(ShopOrderEntity shopOrder : orderEntityList){
                if(StringUtils.isNotBlank(shopOrder.getInterpreterId())){
                    orderIdList.add(shopOrder.getShopOrderId());
                }
                orderId2Order.put(shopOrder.getShopOrderId(), shopOrder);
            }

            List<InterCalendar4OrderVo> interCalendarList = interpreterApi.getInterCalendarList(orderIdList);
            Map<String, InterCalendar4OrderVo> orderId2InterCalendarMap = null;
            if(CollectionUtils.isNotEmpty(interCalendarList)){
                orderId2InterCalendarMap = interCalendarList.stream().collect(Collectors.toMap(InterCalendar4OrderVo::getOrderId, calendarVo -> calendarVo));
            }
            if(orderId2InterCalendarMap == null){
                orderId2InterCalendarMap = new HashMap<>();
            }

            ShopOrderVo shopOrderVo = null;
            for(ShopOrderEntity shopOrder : orderEntityList){
                String shopOrderId = shopOrder.getShopOrderId();
                shopOrderVo = new ShopOrderVo();
                BeanUtils.copyProperties(shopOrder, shopOrderVo);
                if(orderId2InterCalendarMap.containsKey(shopOrderId)){
                    shopOrderVo.setCalendarVo(orderId2InterCalendarMap.get(shopOrderId));
                }

                shopOrderVoList.add(shopOrderVo);
            }

            return InterOrderResponse.listAndCount(shopOrderVoList, shopOrderVoList.size());
        }

        return InterOrderResponse.listAndCount(shopOrderVoList, shopOrderVoList.size());
    }

    @ApiOperation(value="提交订单时，计算订单价格", notes="提交订单时，计算订单价格")
    @ApiResponses({
            @ApiResponse(code = 200, response = PrePayOrderDataResponse.class, message = "提交订单时，计算订单价格")
    })
    @PostMapping(value = "/calculateorder", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?>  commitOrder2Calculate(HttpServletRequest request,
            @RequestBody InterpreterOrderAddition interpreterOrderAddition) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("用户未登录或不存在");
        }

        if(userInfo4UserCouponVo.isAnonymous()){
            return GenericResponse.ng("此帐户为匿名登录,暂不能购票,请注册后预约讲解员");
        }

        if(interpreterOrderAddition == null){
            return GenericResponse.ng("RequestBody 不能为空");
        }
        String interpreterId = interpreterOrderAddition.getInterpreterId();
        String sitesId = interpreterOrderAddition.getShopId();
        SKUEntity skuEntity = skuService.getInterpreterSkuById(sitesId, interpreterId);
        if(skuEntity==null || StringUtils.isBlank(skuEntity.getId())){
            return GenericResponse.ng("此讲解员不存在");
        }
        SPUEntity spuEntity = spuService.getByShopIdAndSpuCode(sitesId, skuEntity.getSpuCode());
        if(spuEntity == null){
            return GenericResponse.ng("此讲解员不存在!");
        }
        SitesInfo4SocialVo siteInfo4Social = sitesApi.getSiteInfo4Social(sitesId);
        if(siteInfo4Social==null || StringUtils.isBlank(siteInfo4Social.getName())){
            return GenericResponse.ng("此景区不存在");
        }

        double totalAmount = skuEntity.getDiscountPrice()/100.0D;

        //优惠券相关
        long currentMillis = System.currentTimeMillis();
        String userCouponId = interpreterOrderAddition.getUserCouponId();//用户优惠券ID
        boolean useCoupon = false;
        if(StringUtils.isNotBlank(userCouponId)){
            UserCouponEntity userCouponEntity = userCouponService.getUserCouponById(userCouponId);

            if(userCouponEntity!=null && StringUtils.equals(userId, userCouponEntity.getUserId())
                    && UserCouponEntity.StateEnum.NOUSE.value()==userCouponEntity.getState()
                    && currentMillis<userCouponEntity.getExpirationDate()
                    && userCouponEntity.getEffectiveDate() < currentMillis){

                //判断优惠券类型。是否满减或者直接减金额
                if(totalAmount >= userCouponEntity.getMinSpendingAmountForUse()){
                    //设置总金额
                    totalAmount = (totalAmount - userCouponEntity.getDenomination());
                }
            }
        }

        if(totalAmount <= 0.0){
            return GenericResponse.ng("最终价格必须大于0");
        }

        PrePayOrder prePayOrder = new PrePayOrder();
        prePayOrder.setTotalAmount(totalAmount);
        return PrePayOrderDataResponse.okWithData(prePayOrder);
    }

}

